namespace Stee.CAP8.Entity
{
    using System;
    using System.Text;
    /// <summary>
    /// BaseEntity Class
    /// All entities shall derived from this is an abstract class .
    /// </summary>
    public abstract class BaseEntity : IDataState
    {
        /// <summary>
        /// Unified Identitifier
        /// </summary>
        public virtual long ID { get; set; }
        /// <summary>
        /// Unified identifier for client request.
        /// This property is used to check duplicated request from client.
        /// </summary>
        public virtual Guid RequestID { get; set; }
        /// <summary>
        /// Version shall be increased whenever there are any attribute being modified.
        /// The property is also used for cache.
        /// If the entity need to be cached, it must store Version property into database.
        /// </summary>
        public virtual long Version { get; set; }

        /// <summary>
        /// Audit Properties
        /// Entity Creation Datetime
        /// </summary>
        public virtual DateTime CreationDT { get; set; }
        /// <summary>
        /// Audit Properties
        /// Entity Creation User ID
        /// </summary>
        public virtual long? CreationBy { get; set; }
        /// <summary>
        /// Audit Properties
        /// Entity Update Datetime
        /// </summary>
        public virtual DateTime UpdateDT { get; set; }
        /// <summary>
        /// Audit Properties
        /// Entity Update User ID
        /// </summary>
        public virtual long? UpdateBy { get; set; }

        /// <summary>
        /// LastUpdate property is used by Cache.
        /// If the entity need to be cached, it must store LastUpdate property into database.
        /// </summary>
        public virtual DateTime LastUpdate { get; set; }

        public override string ToString()
        {
            var builder = new StringBuilder();
            builder.Append("EntityType: ")
                .Append(this.GetType().Name).Append("; ")
                .Append("ID: ").Append(this.ID).Append("; ")
                .Append("Version: ").Append(this.Version).Append("; ");
            return builder.ToString();
        }

        public override bool Equals(object obj)
        {
            if (!(obj is BaseEntity currentObject))
            {
                return false;
            }

            return Equals(this.ID,currentObject.ID);
        }

        public override int GetHashCode() => this.ID.GetHashCode();
        /// <summary>
        /// Default clone function.
        /// The MemberwiseClone method creates a shallow copy by creating a new object, and then copying the nonstatic fields of the current object to the new object.
        /// If a field is a value type, a bit-by-bit copy of the field is performed. If a field is a reference type, the reference is copied but the referred object is not;
        /// therefore, the original object and its clone refer to the same object.
        /// </summary>
        /// <returns></returns>
        public virtual object Clone() => this.MemberwiseClone();

        /// <summary>
        /// DataState, When user delete the entity, mark this property to DataState.Deleted.
        ///</summary>
        public virtual DataState DataState { get; set; } = DataState.Active;
    }


}
